﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Net;
using Newtonsoft.Json.Linq;
using System.Web.Security;
using System.Security.Cryptography;
using System.Text;
using EC_ASS.Models;
using Recaptcha;
using Mvc.Mailer;
using EC_ASS.Mailers;
using System.Threading.Tasks;
using System.IO;

namespace EC_ASS.Controllers
{
    public class AccountController : Controller
    {

        private IUserMailer _userMailer = new UserMailer();
        public IUserMailer UserMailer
        {
            get { return _userMailer; }
            set { _userMailer = value; }
        }

        //
        // GET: /Account/
        public ActionResult Index(string id, string name, string ref_url)
        {
            if (Session["CUST"] == null)
            {
                return RedirectToAction("Login", "Account", new { ref_url = Request.RawUrl });
            }
            else
            {
                Customer customer = (Customer)Session["CUST"];
                ViewBag.UserName = customer.Name;
                return View(customer);
            }
        }

        // Partial menu for reload only
        public ActionResult _LoadLoginMenu()
        {
            return PartialView("_LoadLoginMenu");
        }

        [HttpGet]
        public ActionResult Login(string ref_url, string error)
        {
            if (Session["CUST"] != null)
            {
                return RedirectToAction("Index", "Home");
            }
            else
            {
                ViewBag.URL = ref_url;
                if (!String.IsNullOrEmpty(error))
                {
                    ViewBag.MSM = error;
                }
                return View();
            }
        }

        [HttpPost]
        public ActionResult Login(FormCollection form)
        {
            DataECDataContext context = new DataECDataContext();
            try
            {
                Customer customer = context.Customers.Single(tmp => tmp.Account == form.Get("account").ToString()
                                                && tmp.Password == MD5Hash(form.Get("password").ToString()));
                if (customer != null)
                {
                    Session.Add("CUST", customer);

                    if (String.IsNullOrEmpty(form.Get("ref_url").ToString()))
                    {
                        return RedirectToAction("Index", "Home");
                    }
                    else
                    {
                        Session.Add("URL", form.Get("ref_url").ToString());
                        return Redirect(form.Get("ref_url").ToString());
                    }
                }
            }
            catch (System.Exception ex)
            {
                ViewBag.ERROR = "Thông tin không chính xác.";
            }
            return RedirectToAction("Login", "Account", new { error = ViewBag.ERROR });
        }

        [HttpPost]
        public JsonResult LoginAjax(FormCollection form)
        {
            DataECDataContext context = new DataECDataContext();
            Customer customer = new Customer();
            try
            {
                customer = context.Customers.Single(tmp => tmp.Account == form.Get("account").ToString()
                                                && tmp.Password == MD5Hash(form.Get("password").ToString()));
            }
            catch (System.Exception ex)
            {
                customer = null;
            }
            if (customer != null)
            {
                Session.Add("CUST", customer);
                return Json(new { success = true});
            }
            else
            {
                Response.StatusCode = (int) HttpStatusCode.BadRequest;
                return Json(new { success = false});
            }
        }

        [HttpGet]
        public ActionResult Register()
        {

            if (Session["CUST"] != null)
            {
                return RedirectToAction("Index", "Home");
            }
            else
            {
                return View();
            }
        }

        [HttpPost]
        [RecaptchaControlMvc.CaptchaValidatorAttribute]
        public ActionResult Register(FormCollection form, bool captchaValid)
        {
            DataECDataContext context = new DataECDataContext();
            if (!captchaValid)
            {
                ViewBag.MS = "Captcha không chính xác.";
                return View();
            }
            else
            {
                Customer customer = new Customer();
                customer.Account = form.Get("reg_account").ToString();
                customer.Name = form.Get("reg_name").ToString();
                customer.Password = MD5Hash(form.Get("reg_password").ToString());
                customer.Email = form.Get("reg_email").ToString();
                customer.VIP = false;
                customer.Avatar = "img/user-avatar/default-avatar.jpg";
                context.Customers.InsertOnSubmit(customer);
                context.SubmitChanges();
                UserMailer.Welcome(customer.Email, customer.Name).SendAsync();
                return RedirectToAction("Login", "Account");
            }
        }

        public ActionResult Info()
        {
            if (Session["CUST"] == null)
            {
                return RedirectToAction("Login", "Account", new { ref_url = Request.RawUrl });
            }
            else
            {
                return View();
            }
        }

        [HttpGet]
        public ActionResult Logout()
        {
            Session.Remove("CUST");
            return RedirectToAction("Index", "Home");
        }

        [HttpGet]
        public ActionResult ViewOrder()
        {
            if (Session["CUST"] == null)
            {
                return RedirectToAction("Login", "Account", new { ref_url = Request.RawUrl });
            }
            else
            {
                DataECDataContext context = new DataECDataContext();
                Customer customer = (Customer)Session["CUST"];
                var orders = context.Orders.Where(tmp => tmp.CustomerID == customer.ID).ToList();
                ViewBag.USER = customer;
                return View(orders);
            }
        }

        // Get order detail
        [HttpGet]
        public ActionResult OrderDetail(string id)
        {
            DataECDataContext context = new DataECDataContext();
            var detailList = (from p in context.Products
                              join ord in context.DetailOrders on p.ID equals ord.ProductID
                              where ord.OrderID == Int32.Parse(id)
                              select new OrderDetailModel { DetailItem = p, Orders = ord }).ToList();
            return PartialView("_LoadDetailOrder", detailList);
        }

        // Password reset
        [HttpGet]
        public ActionResult ResetPassword()
        {
            if (Session["CUST"] != null)
            {
                return RedirectToAction("Index", "Home");
            }
            else
            {
                return View();
            }
        }

        [HttpPost]
        [RecaptchaControlMvc.CaptchaValidatorAttribute]
        public ActionResult ResetPassword(FormCollection form, bool captchaValid)
        {
            DataECDataContext context = new DataECDataContext();
            string email = form.Get("rs_email").ToString();
            string account = form.Get("rs_account").ToString();
            if (!captchaValid)
            {
                Response.StatusCode = (int)HttpStatusCode.BadRequest;
                return Json(new { errors = true });
            }
            else
            {
                try
                {
                    var foundedAccount = context.Customers.Single(tmp => tmp.Account.Equals(account) && tmp.Email.Equals(email));
                    if (foundedAccount != null)
                    {
                        // Reset password
                        string newPassword = GeneratePassword(10);
                        foundedAccount.Password = MD5Hash(newPassword);
                        context.SubmitChanges();
                        // Send email
                        UserMailer.PasswordReset(foundedAccount.Email, foundedAccount.Name, newPassword).SendAsync();
                        return Json(new { success = true });
                    }
                }
                catch (System.Exception ex)
                {
                    Response.StatusCode = (int)HttpStatusCode.BadRequest;
                }
                return Json(new { errors = true });
            }
        }

        [HttpPost]
        public ActionResult CheckExistedAccount(string stringToCheck) {
            DataECDataContext context = new DataECDataContext();
            try
            {
                var foundedAccount = context.Customers.Single(tmp => tmp.Account.Equals(stringToCheck));
                return Json(new { success = true });
            }
            catch (System.Exception ex)
            {
                Response.StatusCode = (int)HttpStatusCode.BadRequest;
            }
            return Json(new { errors = true });
        }

        [HttpPost]
        public ActionResult CheckExistedEmail(string stringToCheck)
        {
            DataECDataContext context = new DataECDataContext();
            try
            {
                var foundedEmail = context.Customers.Single(tmp => tmp.Email.Equals(stringToCheck));
                return Json(new { success = true });
            }
            catch (System.Exception ex)
            {
                Response.StatusCode = (int)HttpStatusCode.BadRequest;
            }
            return Json(new { errors = true });
        }

        [HttpPost]
        public ActionResult EditInfo(Customer item, HttpPostedFileBase Avatar)
        {
            DataECDataContext context = new DataECDataContext();
            try
            {
                var foundedCustomer = context.Customers.Single(tmp => tmp.ID == item.ID);
                foundedCustomer.Password = MD5Hash(item.Password);
                foundedCustomer.Address = item.Address;
                foundedCustomer.Phone = item.Phone;

                // Upload customer avatar
                string name = Avatar.FileName;
                // Save name
                string savedName = Path.GetFileName(name).Replace(' ', '-');
                // Save path
                string savePath = Path.Combine(Server.MapPath("~/img/user-avatar"), savedName);
                // Save file
                Avatar.SaveAs(savePath);
                foundedCustomer.Avatar = "img/user-avatar/" + savedName;

                // Submit changes
                context.SubmitChanges();
                return RedirectToAction("Index","Account", foundedCustomer);
            }
            catch (System.Exception ex)
            {
            	Response.StatusCode = (int) HttpStatusCode.BadRequest;
            }
            return Json(new { errors = true, msg = "Cập nhật thất bại!" });
        }

        public ActionResult TestTemplate()
        {
            return View();
        }

        private string MD5Hash(string text)
        {
            MD5 md5 = new MD5CryptoServiceProvider();

            //compute hash from the bytes of text
            md5.ComputeHash(ASCIIEncoding.ASCII.GetBytes(text));

            //get hash result after compute it
            byte[] result = md5.Hash;

            StringBuilder strBuilder = new StringBuilder();
            for (int i = 0; i < result.Length; i++)
            {
                //change it into 2 hexadecimal digits
                //for each byte
                strBuilder.Append(result[i].ToString("x2"));
            }
            return strBuilder.ToString();
        }

        // Random ID  
        private string GeneratePassword(int lengh)
        {
            var chars = "abcdefghiklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
            var random = new Random();
            var result = new string(
                Enumerable.Repeat(chars, lengh)
                          .Select(s => s[random.Next(s.Length)])
                          .ToArray());
            return result;
        }
    }
}
